package com.zrwl.poscloud.core.restapi.admin.authority;


import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.zrwl.poscloud.core.annotion.AuthorityVerify.AuthorityVerify;
import com.zrwl.poscloud.core.annotion.OperationLogger.OperationLogger;
import com.zrwl.poscloud.base.entity.Admin;
import com.zrwl.poscloud.base.entity.MessageSms;
import com.zrwl.poscloud.base.enums.EMessageModelType;
import com.zrwl.poscloud.commons.exception.ThrowableUtils;
import com.zrwl.poscloud.commons.feign.PictureFeignClient;
import com.zrwl.poscloud.commons.holder.RequestHolder;
import com.zrwl.poscloud.commons.utils.*;
import com.zrwl.poscloud.commons.validator.group.GetList;
import com.zrwl.poscloud.commons.validator.group.Insert;
import com.zrwl.poscloud.commons.validator.group.Update;
import com.zrwl.poscloud.xo.global.MessageConf;
import com.zrwl.poscloud.xo.global.RedisConf;
import com.zrwl.poscloud.xo.global.SysConf;
import com.zrwl.poscloud.xo.service.AdminService;
import com.zrwl.poscloud.xo.service.MessageSmsService;
import com.zrwl.poscloud.xo.vo.AdminVO;
import com.zrwl.poscloud.xo.vo.MessageSmsVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 管理员表 RestApi
 *
 * @author liusitong
 * @date 2018-09-04
 */
@RestController
@RequestMapping("/admin")
@Api(value = "管理员相关接口", tags = {"管理员相关接口"})
@Slf4j
public class AdminRestApi {

    @Autowired
    private AdminService adminService;
    @Autowired
    RedisUtil redisUtil;
    @Resource
    private PictureFeignClient pictureFeignClient;
    @Autowired
    private MessageSmsService messageSmsService;

    @AuthorityVerify
    @ApiOperation(value = "获取管理员列表", notes = "获取管理员列表")
    @PostMapping("/getList")
    public String getList(@Validated({GetList.class}) @RequestBody AdminVO adminVO, BindingResult result) {
        // 参数校验
        ThrowableUtils.checkParamArgument(result);
        return adminService.getList(adminVO);
    }
    @AuthorityVerify
    @ApiOperation(value = "获取管理员列表", notes = "获取管理员列表")
    @PostMapping("/getAllList")
    public String getAllList(@Validated({GetList.class}) @RequestBody AdminVO adminVO, BindingResult result) {
        // 参数校验
        ThrowableUtils.checkParamArgument(result);
        return adminService.getAllList(adminVO);
    }

    @AuthorityVerify
    @ApiOperation(value = "获取管理员 带有角色名称的列表", notes = "获取管理员 带有角色名称的列表")
    @PostMapping("/getListJoinRoles")
    public String getListJoinRoles(@Validated({GetList.class}) @RequestBody AdminVO adminVO, BindingResult result) {
        // 参数校验
        ThrowableUtils.checkParamArgument(result);
        return adminService.getListJoinRoles(adminVO);
    }

    @AuthorityVerify
    @OperationLogger(value = "重置用户密码")
    @ApiOperation(value = "重置用户密码", notes = "重置用户密码")
    @PostMapping("/restPwd")
    public String restPwd(@Validated({Update.class}) @RequestBody AdminVO adminVO, BindingResult result) {
        // 参数校验
        ThrowableUtils.checkParamArgument(result);
        return adminService.resetPwd(adminVO);
    }

    @AuthorityVerify
    @OperationLogger(value = "根据手机号获取管理员")
    @ApiOperation(value = "根据手机号获取管理员", notes = "根据手机号获取管理员")
    @PostMapping("/getAdminByMobile")
    public String adminByMobile(@Validated({GetList.class}) @RequestBody AdminVO adminVO, BindingResult result) {
        // 参数校验
        ThrowableUtils.checkParamArgument(result);
        List<Admin> adminList = new ArrayList<>();
        return ResultUtil.successWithData(adminService.getAdminByMobile(adminVO.getMobile()));
    }

    @ApiOperationSupport(order = 1, includeParameters = {"adminVO.userName"})
    @AuthorityVerify
    @OperationLogger(value = "新增管理员")
    @ApiOperation(value = "新增管理员", notes = "新增管理员")
    @PostMapping("/add")
    public String add(@Validated({Insert.class}) @RequestBody AdminVO adminVO, BindingResult result) {
        // 参数校验
        ThrowableUtils.checkParamArgument(result);
        String resultStr = adminService.addAdmin(adminVO);
        return resultStr;
    }

    @AuthorityVerify
    @OperationLogger(value = "更新管理员")
    @ApiOperation(value = "更新管理员", notes = "更新管理员")
    @PostMapping("/edit")
    public String edit(@Validated({Update.class}) @RequestBody AdminVO adminVO, BindingResult result) {
        // 参数校验
        ThrowableUtils.checkParamArgument(result);
        return adminService.editAdmin(adminVO);
    }


    @AuthorityVerify
    @OperationLogger(value = "批量删除管理员")
    @ApiOperation(value = "批量删除管理员", notes = "批量删除管理员")
    @PostMapping("/delete")
    public String delete(@ApiParam(name = "adminUids", value = "管理员uid集合", required = true) @RequestParam(name = "adminUids", required = true) List<String> adminUids) {
        return adminService.deleteBatchAdmin(adminUids);
    }

    @AuthorityVerify
    @ApiOperation(value = "获取在线管理员列表", notes = "获取在线管理员列表", response = String.class)
    @PostMapping(value = "/getOnlineAdminList")
    public String getOnlineAdminList(@Validated({GetList.class}) @RequestBody AdminVO adminVO, BindingResult result) {
        // 参数校验
        ThrowableUtils.checkParamArgument(result);
        return adminService.getOnlineAdminList(adminVO);
    }

    @AuthorityVerify
    @OperationLogger(value = "强退用户")
    @ApiOperation(value = "强退用户", notes = "强退用户", response = String.class)
    @PostMapping(value = "/forceLogout")
    public String forceLogout(@RequestBody AdminVO adminVO) {
        return adminService.forceLogout(adminVO);
    }

    @AuthorityVerify
    @OperationLogger(value = "获取当前用户")
    @ApiOperation(value = "获取当前用户", notes = "获取当前用户", response = String.class)
    @PostMapping(value = "/getMe")
    public String getMe() {
        return ResultUtil.successWithData(adminService.getMe().getUid());
    }

    @AuthorityVerify
    @OperationLogger(value = "获取当前用户昵称及公司名称")
    @ApiOperation(value = "获取当前用户昵称及公司名称", notes = "获取当前用户昵称及公司名称", response = String.class)
    @PostMapping(value = "/getPresentMes")
    public String getPresentMes() {
        return ResultUtil.successWithData(adminService.getPresentMes());
    }

    @AuthorityVerify
    @OperationLogger(value = "获取当前用户Token")
    @ApiOperation(value = "获取当前用户Token", notes = "获取当前用户Token", response = String.class)
    @PostMapping(value = "/getPresentAdminToken")
    public String getPresentAdminToken() throws Exception {
        return ResultUtil.successWithData(adminService.getPresentAdminToken());
    }


    @AuthorityVerify
    @OperationLogger(value = "登录名更替为手机号")
    @ApiOperation(value = "登录名更替为手机号", notes = "登录名更替为手机号", response = String.class)
    @PostMapping("/mobileReplaceUserName")
    public String mobileReplaceUserName() {
        AdminVO me = adminService.getMe();
        if (me.getUserName().equals(me.getMobile())) {
            return ResultUtil.errorWithMessage("内容一致,无需替换");
        }
        if (StringUtils.isEmpty(me.getMobile()) || StringUtils.isEmpty(me.getMobile().trim())) {
            return ResultUtil.errorWithMessage("手机号不可为空");
        }

        me.setUserName(me.getMobile());
        adminService.editMe(me);
        return ResultUtil.successWithMessage("成功更换");
    }

    @AuthorityVerify
    @OperationLogger(value = "手机号修改密码")
    @ApiOperation(value = "手机号修改密码", notes = "手机号修改密码", response = String.class)
    @PostMapping("/mobileChangePwd")
    public String mobileChangePwd(@Validated({Update.class}) @RequestBody AdminVO adminVO, BindingResult result) {
        AdminVO me = adminService.getMe();
        Admin admin = adminService.getById(me.getUid());
        if (adminVO.getMobile().equals(admin.getMobile())) {
            PasswordEncoder encoder = new BCryptPasswordEncoder();
            admin.setPassWord(encoder.encode(adminVO.getPassWord()));
            admin.setUpdateTime(new Date());
            admin.updateById();
            return ResultUtil.successWithMessage(MessageConf.UPDATE_SUCCESS);
        } else {
            return ResultUtil.errorWithMessage("非法操作");
        }
    }
    @AuthorityVerify
    @OperationLogger(value = "解绑/绑定手机")
    @ApiOperation(value = "解绑/绑定手机", notes = "解绑/绑定手机", response = String.class)
    @PostMapping("/bindMobile")
    @Transactional
    public String bindMobile(@Validated({Update.class}) @RequestBody AdminVO adminVO, BindingResult result) {
        // 参数校验
        ThrowableUtils.checkParamArgument(result);
        AdminVO me = adminService.getMe();
        Admin admin = adminService.getById(adminVO.getUid());
        HttpServletRequest request = RequestHolder.getRequest();
        String token = request.getAttribute(SysConf.TOKEN).toString();
        if (adminVO.getOldMobileCode() != null || me.getMobile() == null || me.getMobile() == "" || !adminVO.getMobile().equals(me.getMobile())) {
            if (StringUtils.isEmpty(adminVO.getValidCode()) || StringUtils.isEmpty(adminVO.getValidCode().trim())) {
                throw new RuntimeException("验证码不能为空");
            }
            MessageSms messageSms = null;
            //初次绑定
            if (me.getMobile() == null) {
                try {
                    messageSms = messageSmsService.verificationCode(adminVO.getMobile(), adminVO.getValidCode());
                } catch (RuntimeException r) {
                    throw new RuntimeException(r.getMessage());
                }
                //判断是否有该手机号
                Admin adminByMobile = adminService.getAdminByMobile(adminVO.getMobile());
                if (adminByMobile != null) {
                    throw new RuntimeException("该手机号已被绑定,请解绑后再进行绑定操作");
                }
                admin.setMobile(adminVO.getMobile());
                admin.setUpdateTime(new Date());
                admin.updateById();
            } else if (me.getMobile().equals(adminVO.getOldMobileCode())) {
                if (me.getMobile().equals(adminVO.getMobile())) {
                    throw new RuntimeException("重复绑定");
                }
                //绑定当前用户
                try {
                    messageSms = messageSmsService.verificationCode(adminVO.getMobile(), adminVO.getValidCode());
                } catch (RuntimeException r) {
                    throw new RuntimeException(r.getMessage());
                }
                //判断是否有该手机号
                Admin adminByMobile = adminService.getAdminByMobile(adminVO.getMobile());
                if (adminByMobile != null) {
                    throw new RuntimeException("该手机号已被绑定,请使用其他手机号进行绑定");
                }
                admin.setMobile(adminVO.getMobile());
                admin.setUpdateTime(new Date());
                admin.updateById();
            } else {
                //非当前用户
                try {
                    messageSms = messageSmsService.verificationCode(adminVO.getMobile(), adminVO.getValidCode());
                } catch (RuntimeException r) {
                    throw new RuntimeException(r.getMessage());
                }
                //判断是否有该手机号
                Admin adminByMobile = adminService.getAdminByMobile(adminVO.getMobile());
                if (adminByMobile != null) {
                    throw new RuntimeException("该手机号已被绑定,请解绑后再进行绑定操作");
                }
                admin.setMobile(adminVO.getMobile());
                admin.setUpdateTime(new Date());
                admin.updateById();
            }
            redisUtil.delete(RedisConf.ADMIN_INFO + RedisConf.SEGMENTATION + token);
            adminVO = new AdminVO();
            BeanUtils.copyProperties(admin, adminVO);
            adminVO.setPassWord(null);
            //redis时间需设置
            redisUtil.setEx(RedisConf.ADMIN_INFO + RedisConf.SEGMENTATION + token, JsonUtils.objectToJson(adminVO), 120, TimeUnit.MINUTES);
            return ResultUtil.successWithMessage("成功绑定");
        } else {
            //解绑
            if (StringUtils.isEmpty(adminVO.getValidCode()) || StringUtils.isEmpty(adminVO.getValidCode().trim())) {
                throw new RuntimeException("验证码不能为空");
            }
            MessageSms messageSms = null;
            //解绑当前用户
            if (me.getMobile().equals(adminVO.getMobile())) {
                try {
                    messageSms = messageSmsService.verificationCode(adminVO.getMobile(), adminVO.getValidCode());
                } catch (RuntimeException r) {
                    throw new RuntimeException(r.getMessage());
                }
                adminVO.setUid(me.getUid());
                int i = adminService.unbindMobile(adminVO);
                if (i == 0) {
                    throw new RuntimeException("解绑失败");
                }
            } else {
                //非当前用户
                if (admin.getMobile().equals(adminVO.getMobile())) {
                    try {
                        messageSms = messageSmsService.verificationCode(adminVO.getMobile(), adminVO.getValidCode());
                    } catch (RuntimeException r) {
                        throw new RuntimeException(r.getMessage());
                    }
                    int i = adminService.unbindMobile(adminVO);
                    if (i == 0) {
                        throw new RuntimeException("解绑失败");
                    }
                } else {
                    throw new RuntimeException("非法操作");
                }
            }
            //解绑手机号
        /*  redisUtil.delete(RedisConf.ADMIN_INFO + RedisConf.SEGMENTATION + token);
            adminVO = new AdminVO();
            BeanUtils.copyProperties(admin, adminVO);
            adminVO.setPassWord(null);
            adminVO.setMobile(null);
            //获取图片
            if (StringUtils.isNotEmpty(adminVO.getAvatar())) {
                String pictureList = this.pictureFeignClient.getPicture(adminVO.getAvatar(), Constants.SYMBOL_COMMA);
                adminVO.setPhotoList(webUtil.getPicture(pictureList));
            }
            //redis时间需设置
            redisUtil.setEx(RedisConf.ADMIN_INFO + RedisConf.SEGMENTATION + token, JsonUtils.objectToJson(adminVO), 120, TimeUnit.MINUTES);*/
            return ResultUtil.successWithMessage("成功解绑");
        }
    }

    @AuthorityVerify
    @OperationLogger(value = "获取短信验证码")
    @ApiOperation(value = "获取短信验证码", notes = "获取短信验证码", response = String.class)
    @PostMapping("/obtainSMSCode")
    public String obtainSMSCode(@Validated({GetList.class}) @RequestBody AdminVO adminVO, BindingResult result) {
        // 参数校验
        ThrowableUtils.checkParamArgument(result);
        if (StringUtils.isEmpty(adminVO.getMobile()) || StringUtils.isEmpty(adminVO.getMobile().trim())) {
            return ResultUtil.errorWithMessage("手机号不能为空");
        }
        int number = messageSmsService.getCurrentSMS(adminVO.getMobile());
        if (number >= 10) {
            return ResultUtil.errorWithMessage("获取验证码错误,今天获取次数已上限");
        }
        MessageSmsVO messageSmsVO = new MessageSmsVO();
        messageSmsVO.setMobile(adminVO.getMobile());
        messageSmsVO.setContent(RandomUtils.genSimplePWD() + "##10");
        return messageSmsService.add(messageSmsVO, EMessageModelType.SMS_VERIFICATION_CODE);
    }

}
